/*
 * Tranquil Java Integrated Development Environment
 *
 * The GNU General Public License Version 3
 *
 * Copyright (C) 2021 Autumn Lamonte
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Autumn Lamonte [AutumnWalksTheLake@gmail.com] ⚧ Trans Liberation Now
 * @version 1
 */
package tjide;

import gjexer.TApplication;
import gjexer.TApplication.BackendType;
import gjexer.event.TMenuEvent;

import tjide.project.License;
import tjide.ui.TranquilApplication;

/**
 * Main driver that loads TJIDE.
 */
public class Main {

    /**
     * Set up application to load a project.
     *
     * @param app the application
     * @param projectFilename the project filename
     */
    private static void openProject(final TranquilApplication app,
        final String projectFilename) {

        app.invokeLater(new Runnable() {
            public void run() {
                app.openProject(projectFilename);
            }
        }
        );
    }

    /**
     * Set up application to build a project.
     *
     * @param app the application
     */
    private static void buildProject(final TranquilApplication app) {
        app.invokeLater(new Runnable() {
            public void run() {
                app.postMenuEvent(new TMenuEvent(TranquilApplication.MENU_COMPILE_BUILD_ALL));
            }
        }
        );
    }

    /**
     * Set up application to make a project.
     *
     * @param app the application
     */
    private static void makeProject(final TranquilApplication app) {
        app.invokeLater(new Runnable() {
            public void run() {
                app.postMenuEvent(new TMenuEvent(TranquilApplication.MENU_COMPILE_MAKE));
            }
        }
        );
    }

    /**
     * Set up application to run a project.
     *
     * @param app the application
     */
    private static void runProject(final TranquilApplication app) {
        app.invokeLater(new Runnable() {
            public void run() {
                app.postMenuEvent(new TMenuEvent(TranquilApplication.MENU_RUN_RUN));
            }
        }
        );
    }

    /**
     * Display usage string and exit.
     */
    private static void showUsage() {
        System.err.println("USAGE: java -jar tjide.jar OPTIONS");
        System.err.println();
        System.err.println("OPTIONS:");
        System.err.println();
        System.err.println("   [ --project path/to/filename.project ]");
        System.err.println("   [ --build | --make | --run ]");
        System.err.println("   [ --width columns ] [ --height rows ]");
        System.exit(1);
    }

    /**
     * Main entry point.
     *
     * @param args Command line arguments
     */
    public static void main(final String [] args) {
        TranquilApplication app = null;
        try {

            // Swing is the default backend on Windows unless explicitly
            // overridden by gjexer.Swing.
            BackendType backendType = BackendType.XTERM;
            if (System.getProperty("os.name").startsWith("Windows")) {
                backendType = TApplication.BackendType.SWING;
            }
            if (System.getProperty("os.name").startsWith("Mac")) {
                backendType = TApplication.BackendType.SWING;
            }
            if (System.getProperty("gjexer.Swing") != null) {
                if (System.getProperty("gjexer.Swing",
                        "false").equals("true")) {

                    backendType = TApplication.BackendType.SWING;
                } else {
                    backendType = TApplication.BackendType.XTERM;
                }
            }

            /*
             * Supported arguments:
             *
             * --version
             * --project path/to/project/filename.project
             * --build (requires project)
             * --make (requires project)
             * --run (requires project)
             * --width width
             * --height height
             */
            String projectFilename = null;
            boolean build = false;
            boolean make = false;
            boolean run = false;
            int width = -1;
            int height = -1;
            for (int i = 0; i < args.length; i++) {
                if (args[i].equals("--project")) {
                    if (i == args.length - 1) {
                        showUsage();
                    }
                    projectFilename = args[i + 1];
                    i++;
                    continue;
                }
                if (args[i].equals("--width")) {
                    if (i == args.length - 1) {
                        showUsage();
                    }
                    try {
                        width = Integer.parseInt(args[i + 1]);
                    } catch (NumberFormatException e) {
                        showUsage();
                    }
                    i++;
                    continue;
                }
                if (args[i].equals("--height")) {
                    if (i == args.length - 1) {
                        showUsage();
                    }
                    try {
                        height = Integer.parseInt(args[i + 1]);
                    } catch (NumberFormatException e) {
                        showUsage();
                    }
                    i++;
                    continue;
                }
                if (args[i].equals("--build")) {
                    build = true;
                }
                if (args[i].equals("--make")) {
                    make = true;
                }
                if (args[i].equals("--run")) {
                    run = true;
                }
                if (args[i].equals("--version")) {
                    String version = Main.class.getPackage().getImplementationVersion();
                    if (version == null) {
                        // This is Java 9+, use a hardcoded string here.
                        version = TranquilApplication.VERSION;
                    }
                    System.out.println("TJIDE " + version);
                    System.out.println();
                    System.out.println(License.getLicense("GPL-3").
                        getDescription());
                    System.exit(1);
                }
            }

            // We know we will be starting the application, so set it up.
            if ((width > 0) && (height > 0)) {
                app = new TranquilApplication(backendType, width, height, 20);
            } else {
                if (backendType == BackendType.SWING) {
                    // Let's request a slightly larger window: 90x30, 20
                    // points.  This gives more room for the external editor
                    // window.  And at 20 pts Windows and Linux both appear
                    // to compute the text cell dimensions correctly.
                    app = new TranquilApplication(backendType, 90, 30, 20);
                } else {
                    app = new TranquilApplication(backendType);
                }
            }

            if (projectFilename != null) {
                openProject(app, projectFilename);
                if (build) {
                    buildProject(app);
                } else if (make) {
                    makeProject(app);
                } else if (run) {
                    runProject(app);
                }
            }

            // Just run the app in this thread, no need to spin it off.
            app.run();
        } catch (Throwable t) {
            if (app != null) {
                app.restoreConsole();
            }
            t.printStackTrace();
            System.exit(2);
        }
    }

}
